﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Vikipedia.CommonTools.Subtitles
{
    public  interface   ISubtitleItem
    {
        int IndexIfAvsilable { get; set; }
        TimeSpan Position{get;set;}
        TimeSpan Duration {get;set;}
        object Data { get; set; }
    }
    public interface ISubtitleItem<T> : ISubtitleItem
    {
         T Data { get; set; }
    }
    public struct SubtitleItem<T> : ISubtitleItem<T>
    {

        #region ISubtitleItem<T> Members

        public T Data
        {
            get;
            set;

        }

        #endregion

        #region ISubtitleItem Members

        public TimeSpan Position
        {
            get;
            set;
        }

        object ISubtitleItem.Data
        {
            get
            {
                return this.Data;
            }
            set
            {
                if (!(value is T)) throw new ArgumentException("Value Must be " + typeof(T).ToString ());
                this.Data = (T)value;
            }
        }
        public int  IndexIfAvsilable
        {
        get;set;
        }
        public TimeSpan Duration
        {
            get;
            set;
        }
}
        #endregion


 

    public abstract   class SubtitleReader
    {
        public SubtitleReader()
        {
        
        }

        public static IDictionary<FileInfo, SubtitleReader> GetSubtitles(IList<FileInfo> sources)
        {
            var q =
                sources.Select(
                f =>
                    new
                    {
                        reader = Readers.Values.Where(r => r.IsFormatMatch(f)).FirstOrDefault(),
                        file = f
                    }
                )
                .Where(x => x.reader != null);
            IDictionary<FileInfo, SubtitleReader> rval = new Dictionary<FileInfo, SubtitleReader>();
            q.ToList().ForEach(x => rval.Add(x.file, x.reader));
            return rval;

            
        }

        static public IDictionary<string, SubtitleReader> Readers 
        {
            get
            {
                return null;
            }
        
        }



        public abstract IEnumerable<ISubtitleItem>  GetSubtitleItems(FileInfo file);
        public abstract bool IsFormatMatch(FileInfo file);
        public abstract string Name{get;}

    }

    public class SrtSubtitleReader:SubtitleReader
    {
    

        SubtitleItem <String > CreateItem (List<String> inputls)
        {
            var itm=new SubtitleItem<String >();

            //读取第一行序号
            int i=0;
            int.TryParse(inputls[0],out i);
            itm.IndexIfAvsilable = i; 
   

            //读取第二行时间
      
            var strs = inputls[1].Replace (',','.').Split (new string[]{"-->"}, StringSplitOptions.None  );
            itm.Position = TimeSpan.Parse(strs[0]);
            itm.Duration = TimeSpan.Parse(strs[1]).Add (itm.Position.Negate ());
     

            //读取其他行内容
            itm.Data =string.Join ("\r\n" ,   inputls.Skip(2).ToArray ());
            return itm;
        }
        
        public SrtSubtitleReader()
        { 
            
        }
        public override IEnumerable<ISubtitleItem> GetSubtitleItems(FileInfo file)
        {
            foreach (var ib in GetSubtitleItemStrings(file))
            {

                yield return CreateItem(ib);
            }
   
 
        }

        internal IEnumerable<List<String>> GetSubtitleItemStrings(FileInfo file)
        {
            using (var sr = new System.IO.StreamReader (file.OpenRead (), AOP.Unity.Container.Resolve<Encoding >("Current")   )) 
            {
                List<String> ls = new List<string>();
                while (!sr.EndOfStream)
                {
                    var s = sr.ReadLine();
                    if (s.Trim().Length == 0)
                    { 
                        var rval = ls;
                        ls = new List<string>();
                        yield return rval;
                    }
                    else  ls.Add (s);
                }

            }


        }

        public override bool IsFormatMatch(FileInfo file)
        {
          using (  var sr = file.OpenText())
            {
                for (int i =1;i<5;i++ )
                {
                    string tmp;
                    tmp = sr.ReadLine();  //Index
                    int idx;
                    if (int.TryParse(tmp, out idx)) //Index must ==i
                    {
                        if (idx != i) return false;
                    }
                    else return false ;//index must be int

                    tmp= sr.ReadLine();
                    if (tmp.IndexOf("-->") == -1) return false;  //Time Line
                    tmp = sr.ReadLine(); //Text
                    tmp = sr.ReadLine();//Blank Line
                    if (tmp.Trim().Length != 0) return false;

                }
            };
            return true;
        }

        public override string Name
        {
            get
            {
                return "SrtSubtitleReader";
            }
       
        }
    }

}
